/***************************************************************
*Copyright(c) 2020思特诺(Stduino)All right reserved.
*
*This library is open source and free for individual users. 
*
*For commercial use, please contact service001@stduino.com.
***************************************************************/

#include "StduinoHardwareSerial.h"

volatile char Usart1_ReceiveData;
volatile int Usart_1_Flag=0;
char Usart_1_ReceiveData[100]="";
char Usart_1_ReceiveData_backup[100]="";
volatile char Usart2_ReceiveData;
volatile int Usart_2_Flag=0;
char Usart_2_ReceiveData[100]="";
char Usart_2_ReceiveData_backup[100]="";
volatile char Usart3_ReceiveData;
volatile int Usart_3_Flag=0;
char Usart_3_ReceiveData[100]="";
char Usart_3_ReceiveData_backup[100]="";

void Serial_begin(uint8_t _usart_x,uint32_t Baud)
{
 _usart_rcc_grp(_usart_x)|=_usart_rcc(_usart_x);
 setmode(_usart_prt_tx(_usart_x),OP_AP_50);
 setmode(_usart_prt_rx(_usart_x),IP_FL);
 _usart_grp(_usart_x)->BRR = (72*1000000)/Baud;
 _usart_grp(_usart_x)->CR1 |= 1<<8;
 _usart_grp(_usart_x)->CR1 |= 1<<5;
 _usart_grp(_usart_x)->CR1 |= 0x200C;
 
 switch(_usart_x)
 {
  NVIC_InitTypeDef NVIC_InitStructure;
  
  case 0x00:
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
   break;
   
  case 0x01:
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
   NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
   break;
   
  case 0x02:
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
   NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
   break;
	
  default:
   break;
 }
}

void Serial_write(uint8_t _usart_x,char Char)
{
 _usart_grp(_usart_x)->DR = (Char & (uint16_t)0x01FF);
 
 while(!(_usart_grp(_usart_x)->SR & USART_FLAG_TXE))
 {
  ;
 }
}

void USART1_IRQHandler(void)
{
 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
 {
  Usart1_ReceiveData = USART_ReceiveData(USART1);
  Usart_1_ReceiveData[Usart_1_Flag]=Usart1_ReceiveData;
  Usart_1_Flag++;
 }
 
 USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}

void USART2_IRQHandler(void)
{
 if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
 {
  Usart2_ReceiveData = USART_ReceiveData(USART2);
  Usart_2_ReceiveData[Usart_2_Flag]=Usart2_ReceiveData;
  Usart_2_Flag++;
 }
 
 USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}

void USART3_IRQHandler(void)
{
 if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
 {
  Usart3_ReceiveData = USART_ReceiveData(USART3);
  Usart_3_ReceiveData[Usart_3_Flag]=Usart3_ReceiveData;
  Usart_3_Flag++;
 }
 
 USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}

char Serial_read(uint8_t _usart_x)
{
 char Ch='\0';
 
 if(_usart_x==0x00&&Usart1_ReceiveData!='\0')
 {
  Ch=Usart_1_ReceiveData[0];
  
  for(unsigned int i=0;i<Usart_1_Flag;i++)
  {
   Usart_1_ReceiveData[i]=Usart_1_ReceiveData[i+1];
  }
  
  Usart_1_Flag-=1;
 }else if(_usart_x==0x01&&Usart2_ReceiveData!='\0')
 {
  Ch=Usart_2_ReceiveData[0];

  for(unsigned int i=0;i<Usart_2_Flag;i++)
  {
   Usart_2_ReceiveData[i]=Usart_2_ReceiveData[i+1];
  }

  Usart_2_Flag-=1;
 }else if(_usart_x==0x02&&Usart3_ReceiveData!='\0')
 {
  Ch=Usart_3_ReceiveData[0];

  for(unsigned int i=0;i<Usart_3_Flag;i++)
  {
   Usart_3_ReceiveData[i]=Usart_3_ReceiveData[i+1];
  }

  Usart_3_Flag-=1;
 }
 
 return Ch;
}

uint8_t Serial_available(uint8_t _usart_x)
{
 switch(_usart_x)
 {
  case 0x00:
   return (Usart_1_Flag>0) ? 1:0;
   
  case 0x01:
   return (Usart_2_Flag>0) ? 1:0;
   
  case 0x02:
   return (Usart_3_Flag>0) ? 1:0;
   
  default:
   return 0;
 }
}



char Serial_peek(uint8_t _usart_x)
{
 switch(_usart_x)
 {
  case 0x00:
   return Usart_1_ReceiveData[0];
   
  case 0x01:
   return Usart_2_ReceiveData[0];
   
  case 0x02:
   return Usart_3_ReceiveData[0];
   
  default:
   return 0;
 }
}

char* Serial_peekString(uint8_t _usart_x)
{
 char *Str="";
 
 switch(_usart_x)
 {
  case 0x00:
   Str=Usart_1_ReceiveData;
   break;
   
  case 0x01:
   Str=Usart_2_ReceiveData;
   break;
   
  case 0x02:
   Str=Usart_3_ReceiveData;
   break;
      
  default:
   break;
 }
 
 return Str;
}

char* Serial_readString(uint8_t _usart_x)
{
 char *Str="";
 
 switch(_usart_x)
 {
  case 0x00:
   for(unsigned int i=0;i<Usart_1_Flag;i++)
   {
    Usart_1_ReceiveData_backup[i]=Usart_1_ReceiveData[i];
   }
   
   Usart_1_ReceiveData_backup[Usart_1_Flag]='\0';
   Str=Usart_1_ReceiveData_backup;
   Usart_1_Flag=0;
   Usart_1_ReceiveData[0]='\0';
   break;
   
  case 0x01:
   for(unsigned int i=0; i < Usart_2_Flag; i++)
   {
    Usart_2_ReceiveData_backup[i]=Usart_2_ReceiveData[i];
   }
   
   Usart_2_ReceiveData_backup[Usart_2_Flag]='\0';
   Str=Usart_2_ReceiveData_backup;
   Usart_2_Flag=0;
   Usart_2_ReceiveData[0]='\0';
   break;
   
  case 0x02:
   for(unsigned int i=0; i < Usart_3_Flag; i++)
   {
    Usart_3_ReceiveData_backup[i]=Usart_3_ReceiveData[i];
   }
   
   Usart_3_ReceiveData_backup[Usart_3_Flag]='\0';
   Str=Usart_3_ReceiveData_backup;
   Usart_3_Flag=0;
   Usart_3_ReceiveData[0]='\0';
   
  default:
   break;
 }

 return Str;
}

/***************************************************************
*Copyright(c) 2020思特诺(Stduino)All right reserved.
*
*This library is open source and free for individual users. 
*
*For commercial use, please contact service001@stduino.com.
***************************************************************/
